package com.sdy.hospitalguard.h5.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.common.utils.DateUtil;
import com.sdy.hospitalguard.biz.constants.RedisConstants;
import com.sdy.hospitalguard.biz.dto.PatientDTO;
import com.sdy.hospitalguard.biz.dto.VisitDTO;
import com.sdy.hospitalguard.biz.model.PatientInformation;
import com.sdy.hospitalguard.biz.model.VisitAppointment;
import com.sdy.hospitalguard.biz.service.HospitalUserService;
import com.sdy.hospitalguard.biz.service.PatientInformationService;
import com.sdy.hospitalguard.biz.service.SickbedService;
import com.sdy.hospitalguard.biz.service.VisitAppointmentService;
import com.sdy.hospitalguard.h5.vo.VisitVo;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * <p>
 * 探视
 * </p>
 *
 * @author fb
 * @since 2020/5/13
 */
@Slf4j
@RestController
@RequestMapping("/visit")
@Api(tags = "探视相关接口")
public class VisitController extends BaseController{

    @Autowired
    private VisitAppointmentService visitAppointmentService;
    @Autowired
    private PatientInformationService patientInformationService;
    @Autowired
    private RedisLockRegistry redisLockRegistry;
    @Autowired
    private HospitalUserService hospitalUserService;
    @Autowired
    private SickbedService sickbedService;

    @PostMapping("/selectTimeLimit")
    @ApiOperation(value = "可探视时间展示")
    public Response selectTimeLimit(@RequestBody VisitDTO visitDTO) throws BizException {
        PatientDTO patientDTO = new PatientDTO();
        patientDTO.setAdmissionNumber(visitDTO.getAdmissionNumber());
        patientDTO.setSickbedId(visitDTO.getSickbedId());
        PatientInformation patientInformation = patientInformationService.selectPatient(patientDTO);
        if(patientInformation == null) {
            return Response.error("无此住院信息或已出院!");
        }
        return Response.success(visitAppointmentService.selectTimeLimit(patientInformation.getId()));
    }

    @PostMapping("/apply")
    @ApiOperation(value = "提交探视申请")
    public Response apply(HttpServletRequest request, @RequestBody VisitDTO visitDTO) throws BizException, InterruptedException{
        PatientDTO patientDTO = new PatientDTO();
        patientDTO.setAdmissionNumber(visitDTO.getAdmissionNumber());
        patientDTO.setSickbedId(visitDTO.getSickbedId());
        PatientInformation patientInformation = patientInformationService.selectPatient(patientDTO);
        if(patientInformation == null) {
            return Response.error("无此住院信息或已出院!");
        }
        Integer userId = getUserId(request);
        Integer patientId = patientInformation.getId();
        visitDTO.setUserId(userId);
        visitDTO.setPatientId(patientId);
        Lock lockPatientId = redisLockRegistry.obtain(RedisConstants.LOCK_APPLY_ADDPATIENT_VISIT + patientId);
        if(!lockPatientId.tryLock(10, TimeUnit.SECONDS)) {
            throw new BizException("向同个患者发起的探视申请过于频繁，请规范操作!");
        }
        try {
            visitAppointmentService.saveVisit(visitDTO);
        }finally {
            lockPatientId.unlock();
        }
        return Response.success("提交成功，待审核。");
    }

    @GetMapping("/selectVisitPatient")
    @ApiOperation(value = "探视的患者信息查询")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "status", value = "探视记录状态，0:未探视 1:探视中 2:已探视 3:过期 4:待审核 5:已失效"),
    })
    public Response selectVisitPatient(HttpServletRequest request, Page page, Integer status) {
        Integer userId = getUserId(request);
        LambdaQueryWrapper<VisitAppointment> wrapper= new LambdaQueryWrapper<>();
        wrapper.eq(VisitAppointment::getUserId, userId);
        if (status == 5) {
            // 状态为失效
            wrapper.eq(VisitAppointment::getStatus, 1);
        } else {
            wrapper.eq(VisitAppointment::getVisitState, status);
        }
        wrapper.orderByDesc(VisitAppointment::getCreateTime);
        IPage<VisitAppointment> visitAppointmentListIPage = visitAppointmentService.page(page, wrapper);
        List<VisitAppointment> visitAppointmentList = visitAppointmentListIPage.getRecords();
        List<VisitVo> visitVos = new ArrayList<>();
        for (int i=0; i<visitAppointmentList.size(); i++) {
            VisitVo visitVo = new VisitVo();
            Integer patientId = visitAppointmentList.get(i).getPatientId();
            visitVo.setId(visitAppointmentList.get(i).getId());
            visitVo.setPatientId(patientId);
            visitVo.setName(hospitalUserService.getById(patientInformationService.
                    getById(patientId).getUserId()).getName());
            visitVo.setPhone(hospitalUserService.getById(patientInformationService.
                    getById(patientId).getUserId()).getPhone());
            visitVo.setAdmissionNumber(patientInformationService.
                    getById(patientId).getAdmissionNumber());
            String bedNumber = sickbedService.getById(patientInformationService.getById(patientId).getSickbedId()).getSickbedNumber();
            visitVo.setBedNumber(bedNumber);
            visitVo.setStatus(visitAppointmentList.get(i).getVisitState());
            String time = DateUtil.getDate(visitAppointmentList.get(i).getVisitDate(), "yyyy-MM-dd") + " " +
                    DateUtil.getDate(visitAppointmentList.get(i).getVisitStartTime(), "yyyy-MM-dd HH:mm:ss").substring(11, 16) + "-" +
                    DateUtil.getDate(visitAppointmentList.get(i).getVisitEndTime(), "yyyy-MM-dd HH:mm:ss").substring(11, 16);
            visitVo.setTime(time);
            visitVos.add(visitVo);
        }
        IPage<VisitVo> result = new Page<VisitVo>(page.getCurrent(), page.getSize(),
                visitAppointmentListIPage.getTotal()).setRecords(visitVos);
        return Response.success(result);
    }

    @GetMapping("/selectVisitDetail")
    @ApiOperation(value = "探视详情,暂时不用")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "探视表id"),
    })
    public Response selectVisitDetail(Integer id) {
        return Response.success(visitAppointmentService.getById(id));
    }

}
